package com.CS3340.project;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;

import javax.imageio.ImageIO;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class GameManager implements ActionListener {
	
	private JFrame gameFrame;
	private JPanel gamePanel;
	private JButton musicButton, drawButton, showP1, showP2, readyBet, judgeWinner, nextRound;
	private int musicOn, visibleP1, visibleP2, totalPot, cpu;
	private Sequence s;
	private Sequencer seq;
	private card[] p1Hand;
	private card[] p2Hand;
	private Player p1, p2;
	private dealer d;
	private judge j;
	// c11 = p1 card 1, c12 = p1 card 2, etc
	boolean cardsCreated = false;
	private JLabel c11, c12, c13, c14, c15, c21, c22, c23, c24, c25;
	private JButton keep11, keep12, keep13, keep14, keep15;
	private JButton keep21, keep22, keep23, keep24, keep25;
	private JScrollPane scroller;
	private JTextArea gameLog;
	private File backImg;
	private JLabel p1funds, p2funds, currentPot;
	private boolean clicked;
	
	public GameManager() {
		musicOn = 1;
		visibleP1 = visibleP2 = totalPot = 0;
		cpu = 1; //1 player game by default
		p1Hand = new card[5];
		p2Hand = new card[5];
		d = new dealer();
		backImg = new File("src/images/backred.gif");
		p1 = new Player();
		p2 = new Player();
		clicked = false;
	}
	
	private void buildFrames() {
		//initialize buttons and frames
		gameFrame = new JFrame("CS 3340 Poker");
		gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gameFrame.setSize(800, 600);
		gameFrame.setLocationRelativeTo(null);
		gameFrame.setVisible(false);	
		gameFrame.setResizable(false);
		
		gamePanel = new JPanel();
		gamePanel.setBackground(Color.BLUE);
		gamePanel.setLayout(null);
		gameFrame.add(gamePanel);
		
		musicButton = new JButton("Music On/Off");
		musicButton.addActionListener(this);
		gamePanel.add(musicButton);
		musicButton.setBounds(684, 537, 110, 35);
		
		showP1 = new JButton("Hide/Show P1 Hand");
		showP1.addActionListener(this);
		showP1.setVisible(false);
		gamePanel.add(showP1);
		showP1.setBounds(210, 25, 150, 25);
		
		showP2 = new JButton("Hide/Show P2 Hand");
		showP2.addActionListener(this);
		showP2.setVisible(false);
		gamePanel.add(showP2);
		showP2.setBounds(210, 540, 150, 25);
		
		drawButton = new JButton("Exchange Cards");
		drawButton.addActionListener(this);
		drawButton.setVisible(false);
		gamePanel.add(drawButton);
		drawButton.setBounds(50,282,150,30);
		
		judgeWinner = new JButton("Judge Winner");
		judgeWinner.addActionListener(this);
		judgeWinner.setVisible(false);
		gamePanel.add(judgeWinner);
		judgeWinner.setBounds(50,282,150,30);
		
		readyBet = new JButton("Ready to Bet");
		readyBet.addActionListener(this);
		readyBet.setVisible(false);
		gamePanel.add(readyBet);
		readyBet.setBounds(50,282,110,30);
		
		nextRound = new JButton("Next Round");
		nextRound.addActionListener(this);
		nextRound.setVisible(false);
		gamePanel.add(nextRound);
		nextRound.setBounds(50,282,150,30);
		
		keep11 = new JButton("Keep");
		keep11.addActionListener(this);
		keep11.setVisible(false);
		gamePanel.add(keep11);
		keep11.setBounds(50, 175, 71, 25);
		
		keep12 = new JButton("Keep");
		keep12.addActionListener(this);
		keep12.setVisible(false);
		gamePanel.add(keep12);
		keep12.setBounds(150, 175, 71, 25);
		
		keep13 = new JButton("Keep");
		keep13.addActionListener(this);
		keep13.setVisible(false);
		gamePanel.add(keep13);
		keep13.setBounds(250, 175, 71, 25);
		
		keep14 = new JButton("Keep");
		keep14.addActionListener(this);
		keep14.setVisible(false);
		gamePanel.add(keep14);
		keep14.setBounds(350, 175, 71, 25);
		
		keep15 = new JButton("Keep");
		keep15.addActionListener(this);
		keep15.setVisible(false);
		gamePanel.add(keep15);
		keep15.setBounds(450, 175, 71, 25);
		
		keep21 = new JButton("Keep");
		keep21.addActionListener(this);
		keep21.setVisible(false);
		gamePanel.add(keep21);
		keep21.setBounds(50, 500, 71, 25);
		
		keep22 = new JButton("Keep");
		keep22.addActionListener(this);
		keep22.setVisible(false);
		gamePanel.add(keep22);
		keep22.setBounds(150, 500, 71, 25);
		
		keep23 = new JButton("Keep");
		keep23.addActionListener(this);
		keep23.setVisible(false);
		gamePanel.add(keep23);
		keep23.setBounds(250, 500, 71, 25);
		
		keep24 = new JButton("Keep");
		keep24.addActionListener(this);
		keep24.setVisible(false);
		gamePanel.add(keep24);
		keep24.setBounds(350, 500, 71, 25);
		
		keep25 = new JButton("Keep");
		keep25.addActionListener(this);
		keep25.setVisible(false);
		gamePanel.add(keep25);
		keep25.setBounds(450, 500, 71, 25);
		
		gameLog = new JTextArea();
        gameLog.setEditable(false);
        gameLog.setWrapStyleWord(true);
        gameLog.setLineWrap(true);
        gameLog.append(" Welcome to CS 3340 Poker!\n");
        scroller = new JScrollPane(gameLog);
        scroller.setBounds(575, 50, 200, 450);
        gamePanel.add(scroller);
        
        currentPot = new JLabel("Current Pot Total: " + totalPot);
        currentPot.setFont(new Font ("Arial", Font.BOLD, 18));
        currentPot.setForeground(Color.YELLOW);
        gamePanel.add(currentPot);
        currentPot.setBounds(210, 282, 200, 25);
        
        p1funds = new JLabel("P1 funds: " + p1.displayFunds());
        p1funds.setFont(new Font ("Arial", Font.BOLD, 14));
        p1funds.setForeground(Color.YELLOW);
        gamePanel.add(p1funds);
        p1funds.setBounds(75, 25, 100, 25);
        
        p2funds = new JLabel("P2 funds: " + p2.displayFunds());
        p2funds.setFont(new Font ("Arial", Font.BOLD, 14));
        p2funds.setForeground(Color.YELLOW);
        gamePanel.add(p2funds);
        p2funds.setBounds(75, 540, 100, 25);
	}
	
	private void startGame() {
		Object[] options = {1, 2};
		int choice = JOptionPane.showOptionDialog(null, "How many Players?", 
				"Start Game", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, 
			      null, options, options[0]);
		
		if (choice == JOptionPane.YES_OPTION) {
			cpu = 1;
		}
		else cpu = 0;
		
		gameFrame.setVisible(true);
		playMusic();
		gameLog.append(" Starting Game\n");
		
		drawCards();
		//main driver loop for the game		
		int turn = 1;
		int fold = 0;
		while (p1.displayFunds() > 0 && p2.displayFunds() > 0) {
			d.create_deck();
			d.shuffle();
			antePhase(turn);
			drawPhase(turn);
			fold = betPhase(turn);
			if (fold == -1) {
				p2.winFunds(totalPot);
				totalPot = 0;
				updateFunds();
				turn++;
				continue;
			}
			else if (fold == -2) {
				p1.winFunds(totalPot);
				totalPot = 0;
				updateFunds();
				turn++;
				continue;
			}
			updateFunds();
			exchangePhase(turn);
			fold = betPhase(turn);
			if (fold == -1) {
				p2.winFunds(totalPot);
				totalPot = 0;
				updateFunds();
				turn++;
				continue;
			}
			else if (fold == -2) {
				p1.winFunds(totalPot);
				totalPot = 0;
				updateFunds();
				turn++;
				continue;
			}
			updateFunds();
			judgePhase(turn);
			turn++;
		}
		if (p1.displayFunds() == 0) {
			JOptionPane.showMessageDialog(null, "PLAYER 2 WINS!!!");
			gameLog.append(" PLAYER 2 WINS!!!");
			System.exit(0);
		}
		
		else {
			JOptionPane.showMessageDialog(null, "PLAYER 1 WINS!!!");
			gameLog.append(" PLAYER 1 WINS!!!");
			System.exit(0);
		}
	}
	
	private void antePhase(int turn) {
		gameLog.append(" ****ANTE****\n");
		gameLog.append(" Round " + turn + ": Player 1 Ante's $5\n");
		totalPot += p1.bet(5);
		gameLog.append(" Round " + turn + ": Player 2 Ante's $5\n");
		totalPot += p2.bet(5);
		
		updateFunds();
	}
	
	private void drawPhase(int turn) {
		gameLog.append(" ****DRAW****\n");
		gameLog.append(" Round " + turn + ": Cards are being dealt\n");
		//deal cards to p1 and p2
        p1.getDealt(d.dealHand());
        p2.getDealt(d.dealHand());
        p1Hand = p1.showHand();
        p2Hand = p2.showHand();
		//drawCards();
		visibleP1 = visibleP2 = 0;
		hideP1();
		hideP2();
		showP1.setVisible(true);
		if (cpu == 0)
			showP2.setVisible(true);	//cannot see cpu cards
		gamePanel.invalidate();
		gameFrame.repaint();
	}
	
	private int betPhase(int turn) {
		String input;
		int amount, choice;
		Object[] options = {"Bet", "Check", "Fold"};
		Object[] options2 = {"Call", "Raise", "Fold"};
		Object[] options3 = {"Call", "Fold"};
		gameLog.append(" ****BET****\n");
		gameLog.append(" Look at your cards and click the button when ready to bet\n");
		readyBet.setVisible(true);
		
		synchronized(this) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//if(turn % 2 == 1) {
			choice = JOptionPane.showOptionDialog(null, "What would P1 like to do?",
					"P1 Bet", JOptionPane.YES_NO_CANCEL_OPTION, 
					JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
			
			if (choice == JOptionPane.YES_OPTION) {
				amount = -1;
				while(true) {
					input = JOptionPane.showInputDialog(null,"Please Enter Bet Amount");
					
					try {
						amount = Integer.parseInt(input);
					}
					catch (NumberFormatException e) {
						JOptionPane.showMessageDialog(null, "Please enter a valid integer");
						continue;
					}
					
					if (amount > 0 && amount <= Math.min(p1.displayFunds(), p2.displayFunds())) {
						totalPot += p1.bet(amount);
						gameLog.append(" P1 bets " + amount + "\n");
						break;
					}
					else {
						JOptionPane.showMessageDialog(null, 
								"Amount cannot be negative and must be less than the lower of P1 and P2's funds");
					}
				}
				if (cpu == 1) {
					totalPot += p2.bet(amount);
					gameLog.append(" P2 calls " + amount + "\n");
				}
				else {
					choice = JOptionPane.showOptionDialog(null, "What would P2 like to do?",
							"P2 Bet", JOptionPane.YES_NO_CANCEL_OPTION, 
							JOptionPane.QUESTION_MESSAGE, null, options2, options2[1]);
					
					if (choice == JOptionPane.YES_OPTION) {
						totalPot += p2.bet(amount);
						gameLog.append(" P2 calls " + amount + "\n");
					}
					else if (choice == JOptionPane.NO_OPTION) {
						int raiseAmount;
						while(true) {
							input = JOptionPane.showInputDialog(null,"Please Enter Raise Amount");
							
							try {
								raiseAmount = Integer.parseInt(input);
							}
							catch (NumberFormatException e) {
								JOptionPane.showMessageDialog(null, "Please enter a valid integer");
								continue;
							}
							
							if (raiseAmount > amount && raiseAmount <= Math.min(p1.displayFunds(), p2.displayFunds())) {
								totalPot += p1.bet(amount);
								gameLog.append(" P2 raises " + raiseAmount + "\n");
								break;
							}
							else {
								JOptionPane.showMessageDialog(null, 
										"Raise must be higher than previous bet and less than the lower of P1 and P2's funds");
							}
						}
						choice = JOptionPane.showOptionDialog(null, "What would P1 like to do?",
								"P1 Bet", JOptionPane.YES_NO_OPTION, 
								JOptionPane.QUESTION_MESSAGE, null, options3, options3[1]);
						
						if (choice == JOptionPane.YES_OPTION) {
							totalPot += p1.bet(raiseAmount - amount);
							gameLog.append(" P1 calls " + (raiseAmount - amount) + "\n");
						}
						else {
							gameLog.append(" P1 folds\n");
							return -1;
						}
						
					}
					else {
						gameLog.append(" P2 folds\n");
						return -2;
					}
				}
			}
			else if (choice == JOptionPane.NO_OPTION) {
				gameLog.append(" P1 Checks\n");
				if (cpu == 1) {
					gameLog.append(" P2 Checks\n");
				}
				else {
					choice = JOptionPane.showOptionDialog(null, "What would P2 like to do?",
							"P2 Bet", JOptionPane.YES_NO_CANCEL_OPTION, 
							JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
					
					if (choice == JOptionPane.YES_OPTION) {
						amount = -1;
						while(true) {
							input = JOptionPane.showInputDialog(null,"Please Enter Bet Amount");
							
							try {
								amount = Integer.parseInt(input);
							}
							catch (NumberFormatException e) {
								JOptionPane.showMessageDialog(null, "Please enter a valid integer");
								continue;
							}
							
							if (amount > 0 && amount <= Math.min(p1.displayFunds(), p2.displayFunds())) {
								totalPot += p2.bet(amount);
								gameLog.append(" P2 bets " + amount + "\n");
								break;
							}
							else {
								JOptionPane.showMessageDialog(null, 
										"Amount cannot be negative and must be less than the lower of P1 and P2's funds");
							}
							
						}
						choice = JOptionPane.showOptionDialog(null, "What would P1 like to do?",
								"P1 Bet", JOptionPane.YES_NO_OPTION, 
								JOptionPane.QUESTION_MESSAGE, null, options3, options3[1]);
						
						if (choice == JOptionPane.YES_OPTION) {
							totalPot += p1.bet(amount);
							gameLog.append(" P1 calls " + amount + "\n");
						}
						else {
							gameLog.append(" P1 folds\n");
							return -1;
						}
						
					}
					else if (choice == JOptionPane.NO_OPTION) {
						gameLog.append(" P2 Checks");
						
					}
					else {
						gameLog.append(" P2 folds\n");
						return -2;
					}
				}
				
			}
			else {
				gameLog.append(" P1 folds\n");
				return -1;
			}
		//}
		readyBet.setVisible(false);
		return 0;
	}	
		/*else {
			if (cpu == 0) {
				int choice = JOptionPane.showOptionDialog(null, "What would P2 like to do?",
						"P2 Bet", JOptionPane.YES_NO_CANCEL_OPTION, 
						JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
			
				if (choice == JOptionPane.YES_OPTION) {
					int amount = -1;
					while(true) {
						input = JOptionPane.showInputDialog(null,"Please Enter Bet Amount");
						
						try {
							amount = Integer.parseInt(input);
						}
						catch (NumberFormatException e) {
							JOptionPane.showConfirmDialog(null, "Please enter a valid integer");
							continue;
						}
						
						if (amount > 0 && amount <= Math.min(p1.displayFunds(), p2.displayFunds())) {
							totalPot += p1.bet(amount);
							gameLog.append(" P1 bets " + amount + "\n");
							break;
						}
						else {
							JOptionPane.showConfirmDialog(null, 
									"Amount cannot be negative and must be less than the lower of P1 and P2's funds");
						}
					}
					if (cpu == 1) {
						totalPot += p2.bet(amount);
						gameLog.append(" P2 calls " + amount + "\n");
					}
				
				}
				else if (choice == JOptionPane.NO_OPTION) {
				
				}
				else {
					gameLog.append(" P2 folds\n");
					return -2;
				}
			}
			else {
				gameLog.append(" P2 checks\n");
				int choice = JOptionPane.showOptionDialog(null, "What would P1 like to do?",
						"P1 Bet", JOptionPane.YES_NO_CANCEL_OPTION, 
						JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
				
					if (choice == JOptionPane.YES_OPTION) {
						int amount = -1;
						while(true) {
							input = JOptionPane.showInputDialog(null,"Please Enter Bet Amount");
							
							try {
								amount = Integer.parseInt(input);
							}
							catch (NumberFormatException e) {
								JOptionPane.showConfirmDialog(null, "Please enter a valid integer");
								continue;
							}
							
							if (amount > 0 && amount <= Math.min(p1.displayFunds(), p2.displayFunds())) {
								totalPot += p1.bet(amount);
								gameLog.append(" P1 bets " + amount + "\n");
								break;
							}
							else {
								JOptionPane.showConfirmDialog(null, 
										"Amount cannot be negative and must be less than the lower of P1 and P2's funds");
							}
						}
						totalPot += p2.bet(amount);
						gameLog.append(" P2 calls " + amount + "\n");
						
					}
					else if (choice == JOptionPane.NO_OPTION) {
						gameLog.append(" P1 checks\n");
						gameLog.append(" P2 checks\n");
					}
					else {
						gameLog.append(" P1 folds\n");
						return -1;
					}
			}
		}*/
	
	private void exchangePhase(int turn) {
		gameLog.append(" ****EXCHANGE****\n");
		gameLog.append("Select which cards to exchange and press the button when done\n");
		drawButton.setVisible(true);
		keep11.setVisible(true);
		keep12.setVisible(true);
		keep13.setVisible(true);
		keep14.setVisible(true);
		keep15.setVisible(true);
		
		if (cpu == 0) {
			keep21.setVisible(true);
			keep22.setVisible(true);
			keep23.setVisible(true);
			keep24.setVisible(true);
			keep25.setVisible(true);
		}
		
		synchronized(this) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		gameLog.append(" Round " + turn + ": Cards have been exchanged\n");
	}
	
	private void judgePhase(int turn) {
		judgeWinner.setVisible(true);
		gameLog.append(" ****JUDGE****\n");
		gameLog.append(" Click the button when you are ready for judging\n");
		synchronized(this) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		j = new judge(p1Hand, p2Hand);
		int result = j.result();
		if (result == 1) { //P1 wins
			p1.winFunds(totalPot);
			gameLog.append(" Round " + turn + ": Player 1 wins " + totalPot + "\n");
			totalPot = 0;
		}
		else {
			p2.winFunds(totalPot);
			gameLog.append(" Round " + turn + ": Player 2 wins " + totalPot + "\n");
			totalPot = 0;
		}
		updateFunds();
		visibleP1 = visibleP2 = 1;
		showP1();
		showP2();
		nextRound.setVisible(true);		
		synchronized(this) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private void updateFunds() {
		p1funds.setText("P1 funds: " + p1.displayFunds());
		p2funds.setText("P2 funds: " + p2.displayFunds());
		currentPot.setText("Current Pot Total: " + totalPot);
	}
	
	
	private void showP1() {
		//show contents of P1's hand
		c11.setIcon(new ImageIcon(p1Hand[0].printImage()));
		c12.setIcon(new ImageIcon(p1Hand[1].printImage()));
		c13.setIcon(new ImageIcon(p1Hand[2].printImage()));
		c14.setIcon(new ImageIcon(p1Hand[3].printImage()));
		c15.setIcon(new ImageIcon(p1Hand[4].printImage()));
	}
	
	private void showP2() {
		//show contents of P2's hand
		c21.setIcon(new ImageIcon(p2Hand[0].printImage()));
		c22.setIcon(new ImageIcon(p2Hand[1].printImage()));
		c23.setIcon(new ImageIcon(p2Hand[2].printImage()));
		c24.setIcon(new ImageIcon(p2Hand[3].printImage()));
		c25.setIcon(new ImageIcon(p2Hand[4].printImage()));
	}
	
	private void hideP1() {
		//hide contents of P1's hand
		
		try {
			c11.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c12.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c13.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c14.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c15.setIcon(new ImageIcon(ImageIO.read(backImg)));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		};
		c11.repaint();
	}
	
	private void hideP2() {
		//hide contents of P2's hand
		try {
			c21.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c22.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c23.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c24.setIcon(new ImageIcon(ImageIO.read(backImg)));
			c25.setIcon(new ImageIcon(ImageIO.read(backImg)));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		};
	}
	
	private void drawCards() {
		//draw initial images of cards onto the screen
		try {
			//if (!cardsCreated) {
			c11 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c12 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c13 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c14 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c15 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c21 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c22 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c23 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c24 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			c25 = new JLabel(new ImageIcon(ImageIO.read(backImg)));
			//cardsCreated = true;
			//}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		gamePanel.add(c11);
		c11.setBounds(50, 75, 71, 96);
		gamePanel.add(c12);
		c12.setBounds(150, 75, 71, 96);
		gamePanel.add(c13);
		c13.setBounds(250, 75, 71, 96);
		gamePanel.add(c14);
		c14.setBounds(350, 75, 71, 96);
		gamePanel.add(c15);
		c15.setBounds(450, 75, 71, 96);
		gamePanel.add(c21);
		c21.setBounds(50, 400, 71, 96);
		gamePanel.add(c22);
		c22.setBounds(150, 400, 71, 96);
		gamePanel.add(c23);
		c23.setBounds(250, 400, 71, 96);
		gamePanel.add(c24);
		c24.setBounds(350, 400, 71, 96);
		gamePanel.add(c25);
		c25.setBounds(450, 400, 71, 96);
	}
	
	 private void playMusic() {
         try {
                 //create a midi sequence from a .mid file
         s = MidiSystem.getSequence(new File("src/audio/game-corner.mid"));
 
         // Create a sequencer, make it loop forever until window closes
         seq = MidiSystem.getSequencer();
         seq.open();
         seq.setSequence(s);
         seq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
     
         // Play the midi file
         seq.start();
     } 
         catch (MalformedURLException e) {} 
         catch (IOException e) {} 
         catch (MidiUnavailableException e) {} 
         catch (InvalidMidiDataException e) {}   
	 }
	 
	 @Override
	 public void actionPerformed(ActionEvent e) {
		 if (e.getActionCommand().equals("Music On/Off")) {
			 if (musicOn == 1) {
				 musicOn = 0;	
				 seq.stop();
			 }
			else {
				musicOn = 1;
				seq.start();
			}
		 }
		 else if (e.getActionCommand().equals("Hide/Show P1 Hand")) {
			 if(visibleP1 == 0) {
				 showP1();
				 visibleP1 = 1;
			 }
			 else {
				 hideP1();
				 visibleP1 = 0;		 
			 }
		 }
		 else if (e.getActionCommand().equals("Hide/Show P2 Hand")) {
			 if(visibleP2 == 0) {
				 visibleP2 = 1;
				 showP2();
			 }
			 else {
				 visibleP2 = 0;
				 hideP2();				 
			 }
		 }
		 else if (e.getActionCommand().equals("Exchange Cards")) {
			 //replace cards marked as "Trash" from deck
			 hideP1();
			 hideP2();
			 visibleP1 = visibleP2 = 0;
			 
			//Once replace phase is over, no more need for these buttons
			 drawButton.setVisible(false);
			 keep11.setVisible(false);
			 keep12.setVisible(false);
			 keep13.setVisible(false);
			 keep14.setVisible(false);
			 keep15.setVisible(false);
			 keep21.setVisible(false);
			 keep22.setVisible(false);
			 keep23.setVisible(false);
			 keep24.setVisible(false);
			 keep25.setVisible(false);
			 
			 if (keep11.getForeground() == Color.RED) {
				 p1.exchange(0, d.deal());
				 keep11.setForeground(Color.DARK_GRAY);
				 keep11.setText("Keep");
			 }
			 if (keep12.getForeground() == Color.RED) {
				 p1.exchange(1, d.deal());
				 keep12.setForeground(Color.DARK_GRAY);
				 keep12.setText("Keep");
			 }
			 if (keep13.getForeground() == Color.RED) {
				 p1.exchange(2, d.deal());
				 keep13.setForeground(Color.DARK_GRAY);
				 keep13.setText("Keep");
			 }
			 if (keep14.getForeground() == Color.RED) {
				 p1.exchange(3, d.deal());
				 keep14.setForeground(Color.DARK_GRAY);
				 keep14.setText("Keep");
			 }
			 if (keep15.getForeground() == Color.RED) {
				 p1.exchange(4, d.deal());
				 keep15.setForeground(Color.DARK_GRAY);
				 keep15.setText("Keep");
			 }
			 if (keep21.getForeground() == Color.RED) {
				 p2.exchange(0, d.deal());
				 keep21.setForeground(Color.DARK_GRAY);
				 keep21.setText("Keep");
			 }
			 if (keep22.getForeground() == Color.RED) {
				 p2.exchange(1, d.deal());
				 keep22.setForeground(Color.DARK_GRAY);
				 keep22.setText("Keep");
			 }
			 if (keep23.getForeground() == Color.RED) {
				 p2.exchange(2, d.deal());
				 keep23.setForeground(Color.DARK_GRAY);
				 keep23.setText("Keep");
			 }
			 if (keep24.getForeground() == Color.RED) {
				 p2.exchange(3, d.deal());
				 keep24.setForeground(Color.DARK_GRAY);
				 keep24.setText("Keep");
			 }
			 if (keep25.getForeground() == Color.RED) {
				 p2.exchange(4, d.deal());
				 keep25.setForeground(Color.DARK_GRAY);
				 keep25.setText("Keep");
			 }
			 
			 p1Hand = p1.showHand();
			 p2Hand = p2.showHand();
			 
			 synchronized(this) {
				 notifyAll();
			 }
		 }
		 else if (e.getActionCommand().equals("Judge Winner")) {
			 judgeWinner.setVisible(false);
			 synchronized(this) {
				 notifyAll();
			 }
		 }
		 else if (e.getActionCommand().equals("Next Round")) {
			 nextRound.setVisible(false);
			 synchronized(this) {
				 notifyAll();
			 }
		 }
		 else if (e.getActionCommand().equals("Ready to Bet")) {
			 drawButton.setVisible(false);
			 synchronized(this) {
				 notifyAll();
			 }
		 }
		 else {
			 //toggle between "Keep" and "Trash"
			 if (((JButton) e.getSource()).getText().equals("Keep")) {
				 ((JButton) e.getSource()).setText("Trash");
				 ((JButton) e.getSource()).setForeground(Color.RED);
			 }
			 else {
				 ((JButton) e.getSource()).setText("Keep");
				 ((JButton) e.getSource()).setForeground(Color.DARK_GRAY);
			 }
		 }
	 }
	 
	 public static void main(String[] args) {
		 GameManager g = new GameManager();
		 g.buildFrames();
		 g.startGame();
	 }
}